package com.dacool.helper;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.dacool.http.BaseRequest;
import com.dacool.http.BaseRequest.ResponseHandler;
import com.dacool.http.TrackOrderRequest;
import com.dacool.model.BillTrackInfo;
import com.dacool.model.BillTrackInfo.InfoEntry;
import com.dacool.model.CartItem;
import com.dacool.model.DaCoolTransactionBill;
import com.dacool.util.FileCacheUtil;
import com.dacool.util.ViewUtils;

public class DaCoolHelper {
	public static interface TrackInfoCallback {
		public void didReceiveInfo(boolean success, BillTrackInfo info);
	}

	public static interface CartItemObserver {
		public void cartItemsChanged();
	}

	private DaCoolHelper() {
		Object savedCart = FileCacheUtil.readObject(ViewUtils.getContext(),
				"cart");
		if (savedCart != null && savedCart instanceof ArrayList<?>) {
			cartItems = (ArrayList<CartItem>) savedCart;
		}
	}

	private ArrayList<WeakReference<CartItemObserver>> cartItemObservers = new ArrayList<WeakReference<CartItemObserver>>();

	private ArrayList<CartItem> cartItems = new ArrayList<CartItem>();

	private ArrayList<DaCoolTransactionBill> myBills = new ArrayList<DaCoolTransactionBill>();

	private static Object initLock = new Object();

	private static DaCoolHelper instance;

	public static DaCoolHelper sharedInstance() {
		if (instance == null) {
			synchronized (initLock) {
				if (instance == null)
					instance = new DaCoolHelper();
			}
		}
		return instance;
	}

	public void addCartItemObserver(CartItemObserver observer) {
		synchronized (cartItemObservers) {
			for (WeakReference<CartItemObserver> ref : cartItemObservers) {
				if (ref != null && ref.get() == observer)
					return;
			}
			cartItemObservers
					.add(new WeakReference<DaCoolHelper.CartItemObserver>(
							observer));
		}
	}

	public synchronized void addItem(CartItem item, int amount) {
		boolean needAdd = true;
		for (int i = 0; i < cartItems.size(); i++) {
			CartItem addedItem = cartItems.get(i);
			if (addedItem.getProduct().getId()
					.equals(item.getProduct().getId())) {
				addedItem.setAmount(addedItem.getAmount() + amount);
				needAdd = false;
			}
		}
		if (needAdd) {
			cartItems.add(item);
			item.setAmount(amount);
		}
		FileCacheUtil.writeObject(ViewUtils.getContext(), cartItems, "cart");
		notifyCartItemObservers();
	}

	private void notifyCartItemObservers() {
		for (WeakReference<CartItemObserver> ref : cartItemObservers) {
			if (ref != null && ref.get() != null)
				ref.get().cartItemsChanged();
		}
	}

	public synchronized void removeItem(CartItem item, int amount) {
		for (int i = 0; i < cartItems.size(); i++) {
			CartItem addedItem = cartItems.get(i);
			if (addedItem.getProduct().getId()
					.equals(item.getProduct().getId())) {
				addedItem.setAmount(addedItem.getAmount() - amount);
				if (addedItem.getAmount() == 0)
					cartItems.remove(i);
				FileCacheUtil.writeObject(ViewUtils.getContext(), cartItems,
						"cart");
				notifyCartItemObservers();
				return;
			}
		}
	}

	public synchronized void clearCart() {
		cartItems.clear();
		FileCacheUtil.writeObject(ViewUtils.getContext(), cartItems, "cart");
		notifyCartItemObservers();
	}

	public ArrayList<CartItem> getCartItems() {
		return new ArrayList<CartItem>(cartItems);

	}

	public ArrayList<DaCoolTransactionBill> getMyBills() {
		return myBills;
	}

	public void getBillTrackInfo(long billId, final TrackInfoCallback callback) {
		new TrackOrderRequest().setOrderId(billId)
				.setHandler(new ResponseHandler() {

					@Override
					public void handleResponse(BaseRequest request,
							int statusCode, String errorMsg, String response) {
						if (statusCode != 200) {
							if (callback != null)
								callback.didReceiveInfo(false, null);
						} else {
							boolean success = false;
							BillTrackInfo info = new BillTrackInfo();
							JSONObject object;
							try {
								object = new JSONObject(response);
								success = object.optBoolean("success", false);
								JSONObject data = object.getJSONObject("data");
								info.billID = data.getLong("orderId");
								info.status = data.getString("status");
								JSONArray tracks = data
										.getJSONArray("orderTrack");
								for (int i = 0; i < tracks.length(); i++) {
									JSONObject obj = tracks.getJSONObject(i);
									InfoEntry track = new InfoEntry();
									track.eventDesc = obj.getString("descript");
									track.time = obj.getString("time");
									info.deliverTracks.add(track);
								}
							} catch (JSONException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							if (callback != null)
								callback.didReceiveInfo(success, info);

						}

					}
				}).start();
		if (callback != null)
			callback.didReceiveInfo(false, null);
	}
}
